package com.inspectortime.webapp.util;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;

import com.opensymphony.module.sitemesh.Config;
import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.DecoratorMapper;
import com.opensymphony.module.sitemesh.Page;
import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
import com.opensymphony.module.sitemesh.mapper.DefaultDecorator;

/**
 * The sitemesh AgentDecoratorMapper does not work as desired because it checks
 * for the existence of a file on the webapp file system. Since Spring MVC
 * abstracts paths that doesn't work. So this class removes that check.
 * 
 * Note I did not extend AgentDecoratorMapper because all the stupid methods
 * were private
 * 
 * @see com.opensymphony.module.sitemesh.AgentDecoratorMapper
 * 
 * @author mKvalsvik
 * 
 */
public class SpringMVCAgentDecoratorMapper extends AbstractDecoratorMapper {

	private Map map = null;

	public void init(Config config, Properties properties,
			DecoratorMapper parent) throws InstantiationException {
		super.init(config, properties, parent);
		map = new HashMap();
		initMap(properties);
	}

	public Decorator getDecorator(HttpServletRequest request, Page page) {
		try {
			Decorator result = null;
			final Decorator d = super.getDecorator(request, page);
			String path = modifyPath(d.getPage(), getExt(request
					.getHeader("User-Agent")));

			File decFile = new File(config.getServletContext()
					.getRealPath(path));

			// mads removed: if (decFile.isFile()) {
				result = new DefaultDecorator(d.getName(), path, null) {
					public String getInitParameter(String paramName) {
						return d.getInitParameter(paramName);
					}
				};
			// mads removed: }
			return result == null ? super.getDecorator(request, page) : result;
		} catch (NullPointerException e) {
			return super.getDecorator(request, page);
		}
	}

	/** Get extention for user-agent. */
	private String getExt(String userAgent) {
		Iterator i = map.entrySet().iterator();
		while (i.hasNext()) {
			Map.Entry entry = (Map.Entry) i.next();
			String curr = (String) entry.getKey();
			if (userAgent.indexOf(curr) > -1)
				return (String) entry.getValue();
		}
		return null;
	}

	/** Change /abc/def.jsp into /abc/def-XYZ.jsp */
	private static String modifyPath(String path, String ext) {
		// Mads
		if (ext == null) {
			return path;
		}
		// End Mads
		int dot = path.indexOf('.');
		if (dot > -1) {
			return path.substring(0, dot) + '-' + ext + path.substring(dot);
		} else {
			return path + '-' + ext;
		}
	}

	/** Initialize user-agent mappings. */
	private void initMap(Properties props) {
		Iterator i = props.entrySet().iterator();
		while (i.hasNext()) {
			Map.Entry entry = (Map.Entry) i.next();
			String key = (String) entry.getKey();
			if (key.startsWith("match.")) {
				String match = key.substring(6);
				String ext = (String) entry.getValue();
				map.put(match, ext);
			}
		}
	}

}
